package com.modeler.single_flowable_modeler.config;

import liquibase.Liquibase;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.DatabaseException;
import liquibase.resource.ClassLoaderResourceAccessor;
import lombok.Data;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.ui.common.service.exception.InternalServerErrorException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;

/**
 * flowable实例配置
 * 配置Liquibase数据库变更,防止找不到act_de_前缀的表
 */
@Data
@Configuration
@ConfigurationProperties("spring.datasource")
public class FlowableBeanConfiguration {

	private String driverClassName;
	private String url;
	private String username;
	private String password;

	/**
	 * Liquibase变动日志表指定前缀,防止跟业务表交叉
	 */
	private static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_DE_";

	@Bean
	public DataSource dataSource(){
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName(driverClassName);
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		return dataSource;
	}

	@Bean
	public Liquibase modelerLiquibase(DataSource dataSource) {
		Liquibase liquibase = null;
		try {
			DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());
			Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
			database.setDatabaseChangeLogTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogTableName());
			database.setDatabaseChangeLogLockTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogLockTableName());
			liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);
			liquibase.update("flowable");
			return liquibase;
		} catch (Exception e) {
			throw new InternalServerErrorException("创建liquibase数据库时出错", e);
		} finally {
			closeDatabase(liquibase);
		}
	}

	private void closeDatabase(Liquibase liquibase) {
		if (liquibase != null) {
			Database database = liquibase.getDatabase();
			if (database != null) {
				try {
					database.close();
				} catch (DatabaseException e) {
					e.printStackTrace();
				}
			}
		}
	}



}
